package com.mango.ch07;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.util.StringUtils;

public class MBAMaper extends Mapper<LongWritable, Text, Text, IntWritable> {
	private int DEFAULT_NUMBER_OF_PAIRS = 2;
	private Text reducerKey = new Text();
	// 设置常量，成对项数
	private static final IntWritable NUMBER_ONE = new IntWritable(1);

	@Override
	protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		String line = value.toString().trim();
		List<String> items = convertItemsToList(line);// 将一行数据转换为list
		if ((items == null) || (items.isEmpty())) {
			// 若没有数据，则推出当前map方法的执行
			// 不会生成映射器
			return;
		}
		// 生成mapper的输出
		generateMapperOutput(DEFAULT_NUMBER_OF_PAIRS, items, context);
	}

	/**
	 * 这个方法对输入的列表排序建立一个键值对 ，键是交易中的一个商品组合 值=1 这里需要排序以却保（a,b）和（b，a) 表示为一个键
	 * 
	 * @param dEFAULT_NUMBER_OF_PAIRS2
	 * @param items
	 * @param context
	 */
	private void generateMapperOutput(int DEFAULT_NUMBER_OF_PAIRS, List<String> items,
			Mapper<LongWritable, Text, Text, IntWritable>.Context context) {
		// TODO Auto-generated method stub
		// 该方法将两个值组成一个值对，并确保生成无误，如(a,b) 和(b,a)是同一个的值对才是正确的
		List<List<String>> sortedCombinations = Combination.findSortedCombinatinos(items, DEFAULT_NUMBER_OF_PAIRS);
		for (List<String> list : sortedCombinations) {
			reducerKey.set(list.toString());
			System.out.println("即将写出的键是" + reducerKey);
			try {
				context.write(reducerKey, NUMBER_ONE);// NUMBER_ONE=1 常量
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("数据写出失败");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("数据写出失败");
			}
		}
	}

	@Override
	protected void setup(Mapper<LongWritable, Text, Text, IntWritable>.Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		// 获取初设定的始化配置
		this.DEFAULT_NUMBER_OF_PAIRS = Integer.valueOf(context.getConfiguration().get("number.of.pairs"));
	}

	/**
	 * 将一行数据转换为String类型的list列表
	 * 
	 * @param line
	 * @return
	 */
	public List<String> convertItemsToList(String line) {
		if ((line == null) || line.length() == 0) {
			return null;
		}
		String[] tokens = StringUtils.split(line, ',');
		if (tokens == null || tokens.length == 0) {
			return null;
		}
		List<String> items = new ArrayList<>();
		for (String t : tokens) {
			if (t != null)
				items.add(t);
		}
		return items;
	}

}
